#ifndef STG_MGR_HH
#define STG_MGR_HH

int fDebugON=0;

class stm {
	char file_name[FILE_NAME_LENGTH];
	int file_type;
	FILE *fp;

public:
	stm(char *filename, int file_ext);
	~stm();

	int read_block(int blocknum,  char *block_buffer);
	int write_block(int blocknum, char *block_buffer);

	int read_buffer(long file_offset, char *buffer, int size);
	int write_buffer(long file_offset, char *buffer, int size);

	int flush();

	/*** Ger functions to get the filename etc... ***/
	char*	get_file_name()	{ return(file_name); }
	int	get_file_type()	{ return(file_type); }

};

stm :: stm(char *filename, int file_ext)
{
	char full_name[FILE_NAME_LENGTH];

	strcpy(file_name, filename);
	
	strcpy(full_name, file_name);
	DBGPRINTS(filename);

	switch(file_ext)
	{
		case TABLE_TYPE_FILE:
			strcat(full_name, ".tbl");
			break;
		case INDEX_TYPE_FILE:
			strcat(full_name, ".idx");
			break;
		case CATALOG_TYPE_FILE:
			strcat(full_name, ".db");
			break;
	}

	if( (fp=fopen(full_name,"rb+")) == NULL )
	{
		DBGPRINTF("NEW FILE\n");
		file_type = NEW_FILE;
		if((fp=fopen(full_name, "wb+")) == NULL)
		{
			DBGPRINTS(full_name);
			FATAL("Cannot create (or) open the file\n");
		}
	}
	else 
	{
		DBGPRINTF("DISK FILE\n");
		file_type = DISK_FILE;
	}
	strcpy(file_name, full_name);
}


int stm :: read_block(int blocknum,  char *block_buffer)
{
	long file_offset= (long) blocknum*BLOCK_LENGTH;
	int num_blocks = 1;

	DBGPRINTS(file_name);
	DBGPRINTS(file_name);
	DBGPRINTN(blocknum);
	DBGPRINTN(file_offset);
	this->read_buffer(file_offset, block_buffer, (num_blocks * BLOCK_LENGTH));

	return(0);

}

int stm :: write_block(int blocknum, char *block_buffer)
{
	long file_offset= (long) (blocknum*BLOCK_LENGTH);
	int num_blocks = 1;
	
	DBGPRINTS(file_name);
	DBGPRINTN(blocknum);
	DBGPRINTN(file_offset);
	this->write_buffer(file_offset, block_buffer, (num_blocks * BLOCK_LENGTH));

	return(0);

}

int stm :: read_buffer(long file_offset, char *buffer, int size)
{
	unsigned int num_buffers=1;

	DBGPRINTS(file_name);
	if(fseek(fp, file_offset, SEEK_SET) )
	{
		DBGPRINTS(file_name);
		DBGPRINTN(file_offset);
		return DATA_NOT_FOUND;
	}		
	

	if(fread(buffer, size, num_buffers, fp) < num_buffers)
	{
		DBGPRINTS(file_name);
		DBGPRINTN(file_offset);
		return DATA_NOT_FOUND;
	}

	if(fDebugON) MEMPRINT(buffer, size);
	return(0);

}

int stm :: write_buffer(long file_offset, char *buffer, int size)
{
	unsigned int num_buffers=1;

	DBGPRINTS(file_name);
	if( fseek(fp, file_offset, SEEK_SET) )
	{
		DBGPRINTS(file_name);
		DBGPRINTN(file_offset);
		return DATA_NOT_FOUND;
	}		
	

	if(fwrite(buffer, size, num_buffers, fp) < num_buffers)
	{
		DBGPRINTS(file_name);
		DBGPRINTN(file_offset);
		return DATA_NOT_FOUND;
	}

	if(fDebugON) MEMPRINT(buffer, size);
	return(0);

}

int stm :: flush()
{
	DBGPRINTS(file_name);
	if(fflush(fp))
	{
		FATAL("Unable to flush the file properly\n");
	}

	return(0);
}

stm :: ~stm()
{
	DBGPRINTS(file_name);
	if(fclose(fp))
	{
		FATAL("flose failed: %s\n",file_name);
	}
}

#endif
